module StarFrame
  class Sprite
    class Collision
      class Rect < Collision
        attr_reader :x, :y, :width, :height
        
        def initialize target, method_name, x, y, width, height
          @x, @y, @width, @height = x, y, width, height
          super
        end
        
        def collide? other
          case other
          when Circle
            return collide_circle?(other)
          when Rect
            left, top, right, bottom = rect
            
            width, height = @width+other.width, @height+other.height
            left, top     = left-other.width, top-other.height
          when Dot
            left, top, right, bottom = rect
          else
            super
          end
          Collision.dot_in_rect?(other.position, [[left, top], [right, bottom]])
        end
        
        private
        def rect
          left, top = position
          right, bottom = left+@width, top+@height
          [left, top, right, bottom]
        end
        
        def collide_circle? other
          left, top, right, bottom = rect
          
          vleft,  vtop    = left-other.radius,  top-other.radius
          vright, vbottom = right+other.radius, bottom+other.radius
          
          other_position = other.position
          return false unless Collision.dot_in_rect?(other_position, [[vleft, vtop], [vright, vbottom]])
          
          case
          when other_position[0] < left
            x = left
          when other_position[0] > right
            x = right
          else
            return true
          end
          
          case
          when other_position[1] < top
            y = top
          when other_position[1] > bottom
            y = bottom
          else
            return true
          end
          
          return Collision.dot_in_circle?([x, y], [other_position, other.radius])
        end
      end
    end
  end
end
